package com.sanron.sunweather.action;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.jsoup.Jsoup;
import org.jsoup.select.Elements;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import com.sanron.sunweather.entity.AirEnvironment;
import com.sanron.sunweather.entity.City;
import com.sanron.sunweather.entity.InstantWeather;
import com.sanron.sunweather.entity.LifeIndex;
import com.sanron.sunweather.entity.Weather;
import com.sanron.sunweather.entity.WeatherData;
import com.sanron.sunweather.utils.DateUtils;
import com.squareup.okhttp.Call;
import com.squareup.okhttp.Callback;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;

/**
 * 天气服务
 *
 */
public class WeatherAction {

	public static final String WEATHER_API1 = "http://wthrcdn.etouch.cn/WeatherApi";
	public static final String WEATHER_API2 = "http://www.weather.com.cn/weather";
	public static final int TIME_OUT = 5; //网络超时时间
	private OkHttpClient httpClient;
	
	private WeatherAction(){
		httpClient = new OkHttpClient();
		httpClient.setConnectTimeout(5, TimeUnit.SECONDS);
	}
	private static WeatherAction instance;
	public static WeatherAction getInstance(){
		if(instance==null){
			synchronized (WeatherAction.class) {
				if(instance==null){
					instance = new WeatherAction();
				}
			}
		}
		return instance;
	}
	
	public void getWeahterData(final City city,final OnGetDataListener onGetDataListener){
		String url = WEATHER_API1+"?city="+city.getName();
		Request request = new Request.Builder().url(url).get().build();
		Call call = httpClient.newCall(request);
		call.enqueue(new Callback() {
			
			@Override
			public void onResponse(Response response) throws IOException {
				final WeatherData weatherData = new WeatherData();
				weatherData.setCity(city.getName());
				try {
					parseXML(weatherData,response.body().byteStream(),onGetDataListener);
				} catch (Exception e){
					e.printStackTrace();
					if(onGetDataListener!=null){
						onGetDataListener.onError("");
					}
					return; 
				}
				String url = WEATHER_API2+"/"+city.getId()+".shtml";
				Request request = new Request.Builder().url(url)
						.get().build();
				Call call = httpClient.newCall(request);
				call.enqueue(new Callback() {
					
					@Override
					public void onResponse(Response response){
						try{
							parseHtml(weatherData, response.body().string(), onGetDataListener);
						}catch(Exception e){
							e.printStackTrace();
							if(onGetDataListener !=null){
								onGetDataListener.onError("");
							}
							return;
						}
						if(onGetDataListener !=null){
							onGetDataListener.onSuccess(weatherData);
						}
					}
					
					@Override
					public void onFailure(Request request, IOException e) {
						if(onGetDataListener!=null){
							onGetDataListener.onError("网络连接错误");
						}
					}
				});
			}
			
			@Override
			public void onFailure(Request request, IOException e) {
				if(onGetDataListener!=null){
					onGetDataListener.onError("网络连接错误");
				}
			}
		});
	}
	

	private void parseHtml(WeatherData weatherData,String html,OnGetDataListener onGetDataListener) throws IOException{
		org.jsoup.nodes.Document document = Jsoup.parse(html);
		Elements elements = document
				.getElementById("zs")
				.getElementsByAttributeValue("class", "clearfix")
				.get(0)
				.getElementsByTag("li");

		List<List<LifeIndex>> lifeIndexs = new ArrayList<List<LifeIndex>>();
		for(int i=0; i<3; i++){
			List<LifeIndex> l = new ArrayList<LifeIndex>();
			lifeIndexs.add(l);
		}
		for(int i=0; i<elements.size(); i++){
			org.jsoup.nodes.Element li = elements.get(i);
			String indexName = li.children().get(0).attr("class");
			Elements days = li.getElementsByTag("aside");
			for(int n=0; n<3; n++){
				LifeIndex lifeIndex = new LifeIndex();
				if("mask ct".equals(indexName)){
					lifeIndex.setName("穿衣指数");
				}else if("mask gl".equals(indexName)){
					lifeIndex.setName("太阳镜指数");
				}else if("mask tr".equals(indexName)){
					lifeIndex.setName("旅游指数");
				}else if("mask yd".equals(indexName)){
					lifeIndex.setName("运动指数");
				}else if("mask xc".equals(indexName)){
					lifeIndex.setName("洗车指数");
				}else if("mask pp".equals(indexName)){
					lifeIndex.setName("化妆指数");
				}else if("mask gm".equals(indexName)){
					lifeIndex.setName("感冒指数");
				}else if("mask uv".equals(indexName)){
					lifeIndex.setName("紫外线指数");
				}else if("mask co".equals(indexName)){
					lifeIndex.setName("舒适度指数");
				}
				lifeIndex.setValue(days.get(n).getElementsByTag("b").get(0).text());
				lifeIndex.setDetail(days.get(n).ownText());
				lifeIndexs.get(n).add(lifeIndex);
			}
		}
		weatherData.setLifeIndexs(lifeIndexs);
	}
	
	
	private void parseXML(WeatherData weatherData,InputStream is,OnGetDataListener onGetDataListener) throws ParserConfigurationException, SAXException, IOException{
		DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
		Document doc = builder.parse(is);
		InstantWeather instantWeather = null;
		AirEnvironment airEnvironment = null;
		Element element = doc.getDocumentElement();
		NodeList childList = element.getChildNodes();
		for(int i=0; i<childList.getLength(); i++){
			Element e = (Element) childList.item(i);
			String tag = e.getTagName();
			String text = e.getTextContent();
			if("error".equals(tag)){
				throw new Error(text);
			}else if("city".equals(tag)){
				instantWeather = new InstantWeather();
			}else if("updatetime".equals(tag)){
				try {
					Calendar calendar = Calendar.getInstance();
					Date hm = DateUtils.parse(text, "HH:mm");
					if(hm.getHours()>calendar.get(Calendar.HOUR_OF_DAY)){
						//如果更新时间大于得到的本地时间，则更新时间可能为昨天的
						calendar.add(Calendar.DATE, -1);
					}
					calendar.set(Calendar.HOUR_OF_DAY, hm.getHours());
					calendar.set(Calendar.MINUTE, hm.getMinutes());
					weatherData.setUpdateTime(calendar);
				} catch (DOMException e1) {
					e1.printStackTrace();
				}
			}else if("wendu".equals(tag)){
				instantWeather.setInstantTEMP(Integer.valueOf(text));
			}else if("fengli".equals(tag)){
				instantWeather.setWindPower(text);
			}else if("shidu".equals(tag)){
				instantWeather.setHumidity(text);
			}else if("fengxiang".equals(tag)){
				instantWeather.setWindDirection(text);
			}else if("sunrise_1".equals(tag) || "sunset_1".equals(tag)){
				Calendar calendar = Calendar.getInstance();
				Date hm = DateUtils.parse(text, "HH:mm");
				calendar.set(Calendar.HOUR_OF_DAY, hm.getHours());
				calendar.set(Calendar.MINUTE, hm.getMinutes());
				if("sunrise_1".equals(tag)){
					instantWeather.setSunriseTime(calendar);
				}else{
					instantWeather.setSunsetTime(calendar);
				}
			}else if("environment".equals(tag)){
				//大气环境
				airEnvironment = new AirEnvironment();
				NodeList nodeList = e.getChildNodes();
				for(int n=0; n<nodeList.getLength(); n++){
					Element e2 = (Element) nodeList.item(n);
					String tag2 = e2.getTagName();
					String text2 = e2.getTextContent();
					if("aqi".equals(tag2)){
						airEnvironment.setAqi(Integer.valueOf(text2));
					}else if("pm25".equals(tag2)){
						airEnvironment.setPm25(Integer.valueOf(text2));
					}else if("pm25".equals(tag2)){
						airEnvironment.setPm25(Integer.valueOf(text2));
					}else if("suggest".equals(tag2)){
						airEnvironment.setSuggest(text2);
					}else if("quality".equals(tag2)){
						airEnvironment.setQuality(text2);
					}else if("MajorPollutants".equals(tag2)){
						airEnvironment.setMajorPollutants(text2);
					}else if("o3".equals(tag2)){
						airEnvironment.setO3(Integer.valueOf(text2));
					}else if("co".equals(tag2)){
						airEnvironment.setCo(Integer.valueOf(text2));
					}else if("pm10".equals(tag2)){
						airEnvironment.setPm10(Integer.valueOf(text2));
					}else if("so2".equals(tag2)){
						airEnvironment.setSo2(Integer.valueOf(text2));
					}else if("no2".equals(tag2)){
						airEnvironment.setNo2(Integer.valueOf(text2));
					}
				}
			}else if("yesterday".equals(tag)){
				//昨日天气
				Weather forecastWeather = new Weather();
				NodeList weatherChilds = e.getChildNodes();
				for(int l=0; l<weatherChilds.getLength(); l++){
					Element e2 = (Element) weatherChilds.item(l);
					String tag2 = e2.getTagName();
					String text2 = e2.getTextContent();
					if("date_1".equals(tag2)){
						Calendar calendar = Calendar.getInstance();
						Pattern pattern = Pattern.compile("\\d+");
						Matcher matcher = pattern.matcher(text2);
						if(matcher.find()){
							calendar.add(Calendar.DATE, -1);
							forecastWeather.setTime(calendar);
						}
					}else if("high_1".equals(tag2)){
						Pattern pattern = Pattern.compile("\\d+");
						Matcher matcher = pattern.matcher(text2);
						if(matcher.find()){
							forecastWeather.setHighTEMP(Integer.valueOf(matcher.group()));
						}
					}else if("low_1".equals(tag2)){
						Pattern pattern = Pattern.compile("\\d+");
						Matcher matcher = pattern.matcher(text2);
						if(matcher.find()){
							forecastWeather.setLowTEMP(Integer.valueOf(matcher.group()));
						}
					}else if("day_1".equals(tag2)){
						NodeList dayChilds = e2.getChildNodes();
						for(int m=0; m<dayChilds.getLength(); m++){
							Element e3 = (Element) dayChilds.item(m);
							String tag3 = e3.getTagName();
							String text3 = e3.getTextContent();
							if("type_1".equals(tag3)){
								forecastWeather.setDayType(text3);
							}else if("fx_1".equals(tag3)){
								forecastWeather.setDayWindDirect(text3);
							}else if("fl_1".equals(tag3)){
								forecastWeather.setDayWindPower(text3);
							}
						}
					}else if("night_1".equals(tag2)){
						NodeList nightChilds = e2.getChildNodes();
						for(int m=0; m<nightChilds.getLength(); m++){
							Element e3 = (Element) nightChilds.item(m);
							String tag3 = e3.getTagName();
							String text3 = e3.getTextContent();
							if("type_1".equals(tag3)){
								forecastWeather.setNightType(text3);
							}else if("fx_1".equals(tag3)){
								forecastWeather.setNightWindDirect(text3);
							}else if("fl_1".equals(tag3)){
								forecastWeather.setNightWindPower(text3);
							}
						}
					}
				}
				weatherData.getWeathers().add(forecastWeather);
				
			}else if("forecast".equals(tag)){
				//当天开始五天天气
				NodeList nodeList = e.getChildNodes();
				for(int n=0; n<nodeList.getLength(); n++){
					Weather forecastWeather = new Weather();
					Element weatherNode = (Element) nodeList.item(n);
					NodeList weatherChilds = weatherNode.getChildNodes();
					for(int l=0; l<weatherChilds.getLength(); l++){
						Element e2 = (Element) weatherChilds.item(l);
						String tag2 = e2.getTagName();
						String text2 = e2.getTextContent();
						if("date".equals(tag2)){
							Calendar calendar = Calendar.getInstance();
							Pattern pattern = Pattern.compile("\\d+");
							Matcher matcher = pattern.matcher(text2);
							if(matcher.find()){
								calendar.add(Calendar.DATE, n);
								forecastWeather.setTime(calendar);
							}
						}else if("high".equals(tag2)){
							Pattern pattern = Pattern.compile("\\d+");
							Matcher matcher = pattern.matcher(text2);
							if(matcher.find()){
								forecastWeather.setHighTEMP(Integer.valueOf(matcher.group()));
							}
						}else if("low".equals(tag2)){
							Pattern pattern = Pattern.compile("\\d+");
							Matcher matcher = pattern.matcher(text2);
							if(matcher.find()){
								forecastWeather.setLowTEMP(Integer.valueOf(matcher.group()));
							}
						}else if("day".equals(tag2)){
							NodeList dayChilds = e2.getChildNodes();
							for(int m=0; m<dayChilds.getLength(); m++){
								Element e3 = (Element) dayChilds.item(m);
								String tag3 = e3.getTagName();
								String text3 = e3.getTextContent();
								if("type".equals(tag3)){
									forecastWeather.setDayType(text3);
								}else if("fengxiang".equals(tag3)){
									forecastWeather.setDayWindDirect(text3);
								}else if("fengli".equals(tag3)){
									forecastWeather.setDayWindPower(text3);
								}
							}
						}else if("night".equals(tag2)){
							NodeList nightChilds = e2.getChildNodes();
							for(int m=0; m<nightChilds.getLength(); m++){
								Element e3 = (Element) nightChilds.item(m);
								String tag3 = e3.getTagName();
								String text3 = e3.getTextContent();
								if("type".equals(tag3)){
									forecastWeather.setNightType(text3);
								}else if("fengxiang".equals(tag3)){
									forecastWeather.setNightWindDirect(text3);
								}else if("fengli".equals(tag3)){
									forecastWeather.setNightWindPower(text3);
								}
							}
						}
					}
					weatherData.getWeathers().add(forecastWeather);
				}
			}
		}
		weatherData.setAirEnvironment(airEnvironment);
		weatherData.setInstantWeather(instantWeather);
	
	}
	
	
	public interface OnGetDataListener{
		public void onSuccess(WeatherData weatherData);
		public void onError(String error);
	}
}
